#include <cmath>
#include <cstdint>
#include <multimedia/image_framework/image/pixelmap_native.h>
#include <multimedia/image_framework/image/image_source_native.h>
#include "ffrt/ffrt.h"


using namespace std;

// 合成装饰外框和头像，实现外框覆盖头像效果
void RevertPixelMapByXY(uint8_t *mainArray, uint8_t *writeArray, uint32_t mainRowBytes, uint32_t writeRowBytes,
                        uint32_t x, uint32_t y, size_t writeArrayLength) {
    size_t writeRowCount = writeArrayLength / writeRowBytes;
    for (int i = 0; i < writeRowCount; i++) {
        int j = 0;
        for (; j < writeRowBytes;) {
            int mainRowIndex = (i + y) * mainRowBytes + x + j;
            int writeRowIndex = i * writeRowBytes + j;
            if (mainArray[mainRowIndex + 3] == 0) {
                mainArray[mainRowIndex] = writeArray[writeRowIndex];
                mainArray[mainRowIndex + 1] = writeArray[writeRowIndex + 1];
                mainArray[mainRowIndex + 2] = writeArray[writeRowIndex + 2];
                mainArray[mainRowIndex + 3] = writeArray[writeRowIndex + 3];
            }
            j += 4;
        }
    }
}

// 覆写头像V标
void OverlayPixelMapByXY(uint8_t *mainArray, uint8_t *overlayWriteArray, uint32_t mainRowBytes, uint32_t writeRowBytes,
                         uint32_t x, uint32_t y, size_t writeArrayLength) {
    size_t writeRowCount = writeArrayLength / writeRowBytes;
    for (int i = 0; i < writeRowCount; i++) {
        int j = 0;
        for (; j < writeRowBytes;) {
            int mainRowIndex = (i + y) * mainRowBytes + x + j;
            int writeRowIndex = i * writeRowBytes + j;
            if (overlayWriteArray[mainRowIndex + 3] != 0) {
                mainArray[mainRowIndex] = overlayWriteArray[writeRowIndex];
                mainArray[mainRowIndex + 1] = overlayWriteArray[writeRowIndex + 1];
                mainArray[mainRowIndex + 2] = overlayWriteArray[writeRowIndex + 2];
                mainArray[mainRowIndex + 3] = overlayWriteArray[writeRowIndex + 3];
            }
            j += 4;
        }
    }
}

// 获取图片基本信息，返回图片物理宽度
uint32_t GetPhyPixelMapInfo(OH_PixelmapNative *pixelmap) {
    // 获取PixelMap原始图片信息
    OH_Pixelmap_ImageInfo *PixelMapInfo;
    OH_PixelmapImageInfo_Create(&PixelMapInfo);
    OH_PixelmapNative_GetImageInfo(pixelmap, PixelMapInfo);

    // 获取物理宽度
    uint32_t pixelMapPhyWidth;
    OH_PixelmapImageInfo_GetWidth(PixelMapInfo, &pixelMapPhyWidth);
    OH_PixelmapImageInfo_Release(PixelMapInfo);
    return pixelMapPhyWidth;
}

// 压缩图片并返回基本信息----物理高度、单行字节数、总字节数
void GetScaledPixelMapInfo(OH_PixelmapNative *pixelMap, uint32_t pixelMapRealWidth2px, uint32_t pixelMapPhyWidth,
                           uint32_t *pixelMapRealHeight2px, uint32_t *pixelMapPerRowCount) {
    // 缩放相框
    double scale = (1.0 * pixelMapRealWidth2px) / pixelMapPhyWidth;
    OH_PixelmapNative_Scale(pixelMap, scale, scale);

    // 获取缩放后信息
    OH_Pixelmap_ImageInfo *ScaledPixelMapInfo;
    OH_PixelmapImageInfo_Create(&ScaledPixelMapInfo);
    OH_PixelmapNative_GetImageInfo(pixelMap, ScaledPixelMapInfo);

    OH_PixelmapImageInfo_GetHeight(ScaledPixelMapInfo, pixelMapRealHeight2px);
    OH_PixelmapImageInfo_GetRowStride(ScaledPixelMapInfo, pixelMapPerRowCount);
    OH_PixelmapImageInfo_Release(ScaledPixelMapInfo);
}

// 将RGBA转化为BGRA，为writeBuffer方法做适配
void RGBA2BGRA(uint8_t *arrayBuffer, size_t arrLength) {
    // 交换R和B值
    for (int i = 0; i < arrLength; i += 4) {
        swap(arrayBuffer[i], arrayBuffer[i + 2]);
    }
}

/**
 * 接受装饰、头像、V标的pixelMap，并完成合成，返回合成后的pixelMap
 * @param decoration
 * @param avatar
 * @param verify
 * @return
 */
void MergeAvatar(OH_PixelmapNative *decoration, OH_PixelmapNative *avatar, OH_PixelmapNative *verify,
                          OH_PixelmapNative **mergedPixelMap) {
    // 定义基准图片大小
    uint32_t avatarSize = 117;
    uint32_t avatarRealWidth2px = avatarSize;
    uint32_t decorationRealWidth2px = ceil(avatarRealWidth2px * 1.2); // 相框为头像的1.2
    uint32_t verifyRealWidth2px = ceil(1.0 * avatarRealWidth2px / 3); // V标为头像的1/3

    // 1.获取图像的实际物理宽度
    // 获取装饰框物理宽度
    uint32_t decorationPhyWidth = GetPhyPixelMapInfo(decoration);

    // 获取头像物理宽度
    uint32_t avatarPhyWidth = GetPhyPixelMapInfo(avatar);

    // 获取V标图片物理宽度
    uint32_t verifyPhyWidth = GetPhyPixelMapInfo(verify);

    // 2、对图片进行缩放，减少计算次数，并获取缩放后的信息（宽高、总字节数、单行字节数）
    uint32_t decorationRealHeight2px;
    uint32_t decorationPerRowCount;

    uint32_t avatarRealHeight2px;
    uint32_t avatarPerRowCount;

    uint32_t verifyRealHeight2px;
    uint32_t verifyPerRowCount;

    ffrt::submit(
        [decoration, decorationRealWidth2px, decorationPhyWidth, &decorationRealHeight2px, &decorationPerRowCount] {
            GetScaledPixelMapInfo(decoration, decorationRealWidth2px, decorationPhyWidth, &decorationRealHeight2px,
                                  &decorationPerRowCount);
        });
    ffrt::submit([avatar, avatarRealWidth2px, avatarPhyWidth, &avatarRealHeight2px, &avatarPerRowCount] {
        GetScaledPixelMapInfo(avatar, avatarRealWidth2px, avatarPhyWidth, &avatarRealHeight2px, &avatarPerRowCount);
    });

    ffrt::submit([verify, verifyRealWidth2px, verifyPhyWidth, &verifyRealHeight2px, &verifyPerRowCount] {
        GetScaledPixelMapInfo(verify, verifyRealWidth2px, verifyPhyWidth, &verifyRealHeight2px, &verifyPerRowCount);
    });
    ffrt::wait();
    
    size_t verifyTotalCount = verifyRealHeight2px * verifyRealWidth2px * 4;
    size_t avatarTotalCount = avatarRealHeight2px * avatarRealWidth2px * 4;
    size_t decorationTotalCount = decorationRealHeight2px * decorationRealWidth2px * 4;

    // 3、将缩放后的图片转换为ArrayBuffer字节数组
    uint8_t *decorationArrayBuffer = new uint8_t[decorationTotalCount];
    uint8_t *avatarArrayBuffer = new uint8_t[avatarTotalCount];
    uint8_t *verifyArrayBuffer = new uint8_t[verifyTotalCount];

    
    ffrt::submit([decoration, decorationArrayBuffer, &decorationTotalCount] {
        OH_PixelmapNative_ReadPixels(decoration, decorationArrayBuffer, &decorationTotalCount);
    });
    
    ffrt::submit([avatar, avatarArrayBuffer, &avatarTotalCount] {
    OH_PixelmapNative_ReadPixels(avatar, avatarArrayBuffer, &avatarTotalCount);
    });
    
    ffrt::submit([verify, verifyArrayBuffer, &verifyTotalCount] {
        OH_PixelmapNative_ReadPixels(verify, verifyArrayBuffer, &verifyTotalCount);
    });
    
    ffrt::wait();
    // 4、对ArrayBuffer进行整合合并计算
    // 整合装饰器和头像像素
    size_t diffByWidth = round((decorationRealWidth2px - avatarRealWidth2px) / 2);
    RevertPixelMapByXY(decorationArrayBuffer, avatarArrayBuffer, decorationPerRowCount, avatarPerRowCount,
                       diffByWidth * 4, diffByWidth, avatarTotalCount);

    // 装饰器和头像整合后，合并V标
    size_t diffByWidthForVerify =
        (decorationRealWidth2px - avatarRealWidth2px) / 2 + (avatarRealWidth2px - verifyRealWidth2px);
    OverlayPixelMapByXY(decorationArrayBuffer, verifyArrayBuffer, decorationPerRowCount, verifyPerRowCount,
                        round(diffByWidthForVerify * 4), floor(diffByWidthForVerify), verifyTotalCount);

    // 由于OH_PixelmapNative_CreatePixelmap写入要求使用BGRA_8888格式，这里先将RGBA转化为BGRA
    RGBA2BGRA(decorationArrayBuffer, decorationTotalCount);

    // 5、将合成完成之后的数据写入PixelMap
    // 创建参数结构体实例，设置参数
    OH_Pixelmap_InitializationOptions *createOpts;
    OH_PixelmapInitializationOptions_Create(&createOpts);
    OH_PixelmapInitializationOptions_SetWidth(createOpts, decorationRealWidth2px);
    OH_PixelmapInitializationOptions_SetHeight(createOpts, decorationRealHeight2px);
    OH_PixelmapInitializationOptions_SetPixelFormat(createOpts, PIXEL_FORMAT_BGRA_8888);
    OH_PixelmapInitializationOptions_SetAlphaType(createOpts, PIXELMAP_ALPHA_TYPE_UNKNOWN);

//     // 创建PixelMap实例
//     OH_PixelmapNative *res = nullptr;
    // 计算完的arrbuffer写入pixelMap
    Image_ErrorCode errCode =
        OH_PixelmapNative_CreatePixelmap(decorationArrayBuffer, decorationTotalCount, createOpts, mergedPixelMap);

    OH_PixelmapInitializationOptions_Release(createOpts);
}